package com.atguigu.vip.spring.framework.aop;


import com.atguigu.vip.spring.framework.aop.intercept.GPMethodInvocation;
import com.atguigu.vip.spring.framework.aop.support.GPAdvisedSupport;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 *
 */
public class GPJdkDynamicAopProxy implements GPAopProxy,InvocationHandler{

    private GPAdvisedSupport advised;

    public GPJdkDynamicAopProxy(GPAdvisedSupport config){
        this.advised = config;
    }

    @Override
    public Object getProxy() {
        return getProxy(this.advised.getTargetClass().getClassLoader());
    }

    @Override
    public Object getProxy(ClassLoader classLoader) {
        return Proxy.newProxyInstance(classLoader,this.advised.getTargetClass().getInterfaces(),this);
    }

    /**
     * 代理增强的逻辑就在 invoke 方法里。
     * 这里是 责任链模式？ ？
     * 拿到拦截器链 然后依次执行
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        /**
         * 拿到拦截器链 - 什么是拦截器链？  比如你add方法 有before 拦截，after拦截，afterThrowing拦截，那么这多组在一起就是拦截器链
         * 每个方法都有一个 拦截器链， 然后把方法名 add作为key，去查拦截器链、  执行拦截器链也是有顺序的，可以自定义。
         * 每个拦截器链其实都是一个 GPMethodInterceptor、
         */
        List<Object> interceptorsAndDynamicMethodMatchers = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, this.advised.getTargetClass());
        GPMethodInvocation invocation = new GPMethodInvocation(proxy, this.advised.getTarget(), method, args, this.advised.getTargetClass(), interceptorsAndDynamicMethodMatchers);
        return invocation.proceed();
    }
}
